/******************************************************************************
Module:  SimpleBinderTester.cs
Notices: Copyright (c) 2002 Jeffrey Richter
Thanks:  To Dario Russi for supplying the initial version of this code.
******************************************************************************/


using System;
using System.Reflection;
using System.Diagnostics;


///////////////////////////////////////////////////////////////////////////////


class App {
   static void Main() {
      Object o = new SomeType();
      Type t = typeof(SomeType);
      SimpleBinder binder = new SimpleBinder();
      BindingFlags bf = BindingFlags.Public | BindingFlags.Instance;

      Int16 b = 5;

      // Calls Void v(Int32)
      t.InvokeMember("v", bf | BindingFlags.InvokeMethod, binder, o, new Object[] { b });

      // Calls Void m(Int32)
      t.InvokeMember("m", bf | BindingFlags.InvokeMethod, binder, o, new Object[] { 1 });

      // Calls Void m(System.Object)
      t.InvokeMember("m", bf | BindingFlags.InvokeMethod, binder, o, new Object[] {new Object()});

      // Calls Void m(Double)
      t.InvokeMember("m", bf | BindingFlags.InvokeMethod, binder, o, new Object[] { 1.4 });

      // Calls Void m(SomeType)
      t.InvokeMember("m", bf | BindingFlags.InvokeMethod, binder, o, new Object[] { o });

      // Calls Void m(System.Object) since m(String) is private
      t.InvokeMember("m", bf | BindingFlags.InvokeMethod, binder, o, new Object[] { "string" });
    
      // Calls Void m(System.String) since NonPublic is specified
      t.InvokeMember("m", bf | BindingFlags.NonPublic | BindingFlags.InvokeMethod, binder, o, new Object[] { "string" });
    
      try {
         // Throws because there is no public method which takes exactly a string 
         t.InvokeMember("m", bf | BindingFlags.InvokeMethod | BindingFlags.ExactBinding, binder, o, new Object[] { "string" });
      }
      catch (MissingMethodException) {
         Console.WriteLine("Invocation failed on m(String), bad binding flags - ExactBinding too restrictive");
      }
    
      try {
         // Throws because there is no method g which takes only 2 args 
         t.InvokeMember("g", bf | BindingFlags.InvokeMethod, binder, o, new Object[] { 1, "string" });
      }
      catch (MissingMethodException) {
         Console.WriteLine("Invocation failed on g(int, Object, String), wrong number of args");
      }
   
      // Calls Void g(Int32, System.Object, System.String)
      t.InvokeMember("g", bf | BindingFlags.InvokeMethod, binder, o, new Object[] { 1, "string", "string" });
   
      // Calls Void h()
      t.InvokeMember("h", bf | BindingFlags.NonPublic | BindingFlags.InvokeMethod, binder, o, new Object[] {});
    
      try {
         // Throws because BindingFlags.Static has not been specified 
         t.InvokeMember("s", bf | BindingFlags.InvokeMethod, binder, o, new Object[] {});
      }
      catch (MissingMethodException) {
         Console.WriteLine("Invocation failed on static s(), bad binding flags - need Static");
      }
      
      // Calls Void s()
      t.InvokeMember("s", bf | BindingFlags.InvokeMethod | BindingFlags.Static, binder, o, new Object[] {});

      // Calls Void m(Int32, Double)
      t.InvokeMember("m", bf | BindingFlags.InvokeMethod, binder, o, new Object[] { 1, 1 });

      Console.WriteLine("Press <Enter> to exit.");
      Console.ReadLine();
   }
}


///////////////////////////////////////////////////////////////////////////////


// A simple class with a bunch of members to test the Binder
class SomeType {
   public void m(Int32 i) {
      Console.WriteLine(new StackTrace().GetFrame(0).GetMethod().ToString());
   }

   public void m(Double d) {
      Console.WriteLine(new StackTrace().GetFrame(0).GetMethod().ToString());
   }
    
   public void m(Object o) {
      Console.WriteLine(new StackTrace().GetFrame(0).GetMethod().ToString());
   }

   public void m(SomeType s) {
      Console.WriteLine(new StackTrace().GetFrame(0).GetMethod().ToString());
   }
    
   public void m(Int32 i, Double m) {
      Console.WriteLine(new StackTrace().GetFrame(0).GetMethod().ToString());
   }
    
   private void m(String s) {
      Console.WriteLine(new StackTrace().GetFrame(0).GetMethod().ToString());
   }
    
   public void g(Int32 i, Object o, String s) {
      Console.WriteLine(new StackTrace().GetFrame(0).GetMethod().ToString());
   }

   private void h() {
      Console.WriteLine(new StackTrace().GetFrame(0).GetMethod().ToString());
   }

   static public void s() {
      Console.WriteLine(new StackTrace().GetFrame(0).GetMethod().ToString());
   }

   public void v(Int32 s) {
      Console.WriteLine(new StackTrace().GetFrame(0).GetMethod().ToString());
   }
}


//////////////////////////////// End of File //////////////////////////////////
